﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using QuantitativeIndicator.Tools;

namespace QuantitativeIndicator.Hurst
{
    class HurstDataModel:DataModel
    {
        //获取指数价格序列,排列按照日期倒序,其中noOfCalPoints可能序列达不到数量，如达不到，则全部选取。

        public double[] getIndexSeries(int noOfCalPoints, string indexTradingCode, string calDate)
        {
            List<string> tmpList = new List<string>();
            tmpList = getIndexTradedDatesList(indexTradingCode,"10000000",calDate);
            //首先需要搞清楚，从calDate往前推，是否有足够的noOfCalPoints个点
            int leftCalPoints;
            leftCalPoints = tmpList.Count();

            if (leftCalPoints < noOfCalPoints)
            {
                noOfCalPoints = leftCalPoints;
            }

            double[] indexPriceList;

            //int leftDatesNum = getIndexTradedDatesNum(indexTradingCode, "10000000", calDate);

            windCommand.CommandText = "select top " + noOfCalPoints.ToString() + " indexDaily.closePrice from dbo.indexDaily,indexList where indexDaily.indexCode=indexList.indexCode and indexList.tradingCode=" + indexTradingCode + " and indexDaily.tradingDate<=" + calDate + " order by indexDaily.tradingDate desc";
            SqlDataReader sdr = windCommand.ExecuteReader();

            indexPriceList = new double[noOfCalPoints];
            int i = 0;

            while (sdr.Read())
            {
                indexPriceList[i] = Double.Parse(sdr["closePrice"].ToString());
                i++;
                //indexPriceList.Add(Double.Parse(sdr["closePrice"].ToString()));
            }
            sdr.Close();
            return indexPriceList;
        }
        //获取交易日列表,缺省获得所有交易日列表
        public List<string> getTradingDate(string startDate = "10000000", string endDate = "99999999")
        {
            windCommand.CommandText = "select * from tradingDates where tradingDate between " + startDate + " and " + endDate + " order by tradingDate";
            SqlDataReader sdr = windCommand.ExecuteReader();
            List<string> tradingDateList = new List<string>();
            //string[] tradingDateArr;
            while (sdr.Read())
            {
                tradingDateList.Add(sdr["tradingDate"].ToString());
            }
            sdr.Close();
            //tradingDateArr = tradingDateList.ToArray();
            return tradingDateList;
        }
        //获取指数收益率，rtnMtd=normal表示普通收益类型，rtnMtd=log表示log收益类型，排列按照日期倒序
        public double[] getIndexRtnSeries(int noOfCalPoints, string indexTradingCode, string calDate, string rtnMtd)
        {
            double[] tmpIndexSeries = getIndexSeries(noOfCalPoints + 1, indexTradingCode, calDate);
            double[] tmpIndexRtnSeries;

            int N = tmpIndexSeries.Length;
            tmpIndexRtnSeries = new double[N - 1];

            for (int i = 0; i < N - 1; i++)
            {
                if (rtnMtd == "normal")
                {
                    tmpIndexRtnSeries[i] = tmpIndexSeries[i] / tmpIndexSeries[i + 1] - 1;
                }
                else if (rtnMtd == "log")
                {
                    tmpIndexRtnSeries[i] = Math.Log10(tmpIndexSeries[i] / tmpIndexSeries[i + 1]);
                }

            }
            return tmpIndexRtnSeries;

        }
        //得到数据库中更新的最近交易日
        public string getLastIndexTradedDate(string indexTradingCode)
        {
            string returnDate;
            windCommand.CommandText = "select max(indexDaily.tradingDate) as lastDate from indexDaily,indexList where indexDaily.indexCode=indexList.indexCode and indexList.tradingCode=" + indexTradingCode;
            SqlDataReader sdr = windCommand.ExecuteReader();
            sdr.Read();
            returnDate = sdr["lastDate"].ToString();
            sdr.Close();
            return returnDate;
        }
        //判断计算日期是否超出最近交易日期
        public Boolean isOutOfIndexLastTradedDate(string indexTradingCode, string calDate)
        {
            string lastDate = getLastIndexTradedDate(indexTradingCode);
            if (int.Parse(calDate) > int.Parse(lastDate))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //得到指数的编制开始日期startDate
        public string getIndexStartDate(string indexTradingCode)
        {
            string tmpDate;
            windCommand.CommandText = "select startDate from indexList where tradingCode=" + indexTradingCode;
            SqlDataReader sdr = windCommand.ExecuteReader();

            sdr.Read();
            tmpDate = sdr["startDate"].ToString();
            sdr.Close();

            return tmpDate;
        }
        //得到指数已交易日期序列,从startDate开始，不考虑回溯数据
        public List<string> getIndexTradedDatesList(string indexTradingCode, string startDate = "10000000", string endDate = "99999999")
        {
            string tmpDate = getIndexStartDate(indexTradingCode);
            if (int.Parse(startDate) < int.Parse(tmpDate))
            {
                startDate = tmpDate;
            }
            List<string> tmpList = new List<string>();
            windCommand.CommandText = "select indexDaily.tradingDate from indexDaily,indexList where indexDaily.indexCode=indexList.indexCode and indexList.tradingCode=" + indexTradingCode + " and indexDaily.tradingDate between " + startDate + " and " + endDate;
            SqlDataReader sdr = windCommand.ExecuteReader();
            while (sdr.Read())
            {
                tmpList.Add (sdr["tradingDate"].ToString());
            }
            sdr.Close();
            return tmpList;
        }



        //获取DFZQ_HurstExponent表中的已计算交易日日期列表，如没有则返回null
        public List<string> getTradedDateListFromDFZQ_HurstExponent(string indexTradingCode,int noOfCalPoints,string hurstStyle)
        {
            windCommand.CommandText = "select tradingDate from dbo.DFZQ_HurstExponent where indexTradingCode='" + indexTradingCode + "' and sampleNum='" + noOfCalPoints.ToString() + "' and hurstStyle='" + hurstStyle + "'";
            SqlDataReader sdr = windCommand.ExecuteReader();
            List<String> tmpList = new List<String>();
            while (sdr.Read())
            {
                if (sdr["tradingDate"] is DBNull)
                {
                    tmpList = null;
                }
                else
                {
                    tmpList.Add(sdr["tradingDate"].ToString());
                }
            }
            sdr.Close();
            return tmpList;
        }
        //判断DFZQ_RSofHurst表中是否存在重复数据
        public Boolean isExitInDFZQ_RSofHurst(string startDate, string indexTradingCode, int noOfCalPoints)
        {
            windCommand.CommandText = "select count(N) as cnt from DFZQ_RSofHurst where startDate='" + startDate + "' and indexTradingCode='" + indexTradingCode + "' and sampleNum='" + noOfCalPoints.ToString()+"'";
            SqlDataReader sdr = windCommand.ExecuteReader();
            sdr.Read();
            int tmpNum = int.Parse(sdr["cnt"].ToString());
            sdr.Close();
            if (tmpNum == 0)
            {
                return false;
            }
            else
            {
               return true;
            }
        }
        //插入DFZQ_HurstExponent表
        public void insertDFZQ_HurstExponent(string tradingDate,string indexTradingCode,int noOfCalPoints,string hurstStyle,double hurstExp)
        {
            windCommand.CommandText = "insert into dbo.DFZQ_HurstExponent values ('" + tradingDate + "','" + indexTradingCode + "','" + noOfCalPoints .ToString() + "','" + hurstStyle + "'," + hurstExp + ")";
            windCommand.ExecuteNonQuery();
        }
        //插入DFZQ_RSofHurst表
        public void insertDFZQ_RSofHurst(string startDate, string indexTradingCode, int noOfCalPoints,double N,double RS,double VStat)
        {
            windCommand.CommandText = "insert into dbo.DFZQ_RSofHurst values ('" + startDate + "','" + indexTradingCode + "','" + noOfCalPoints.ToString() + "'," + N + ", " + RS + ","+ VStat+")";
            windCommand.ExecuteNonQuery();
        }
  
    }
}
